<template xmlns="http://www.w3.org/1999/html">
  <div class="about">
    <div class="thank-container">
      <h1 class="thank-title">这是我们对项目开发中的一些心得体会再次分享给大家，希望你也能有所收获🎉 在此鸣谢！</h1>
      
      <div class="section">
        <h2 class="section-title">👨‍💻 项目开发团队</h2>
        <div class="team-grid">
          <div class="team-member">
            <div class="role">前端开发</div>
            <div class="name">天佑上天</div>
          </div>
          <div class="team-member">
            <div class="role">测试/开发</div>
            <div class="name">星宇啵啵</div>
          </div>
          <div class="team-member">
            <div class="role">后端开发</div>
            <div class="name">小白</div>
          </div>
          <div class="team-member">
            <div class="role">后端开发</div>
            <div class="name">长庚</div>
          </div>
        </div>
        <div class="project-duration">⏳ 项目开发周期: 18天</div>
      </div>
      
      <div class="section">
        <h2 class="section-title">🛠️ 技术栈</h2>
        <div class="tech-stack">
          <div class="tech-category">
            <h3>后端技术</h3>
            <ul>
              <li>Django框架</li>
              <li>Redis数据库</li>
              <li>MySQL数据库</li>
              <li>七牛云存储</li>
              <li>mangodb</li>

            </ul>
          </div>
          <div class="tech-category">
            <h3>API服务</h3>
            <ul>
              <li>支付宝支付</li>
              <li>百度智能云 OCR身份识别,人脸识别,语音播报</li>
              <li>高德 坐标转换 搜索POI2.0 静态地图获取 高德天气</li>
              <li>git第三方登录 </li>
            </ul>
          </div>
          <div class="tech-category">
            <h3>高级功能</h3>
            <ul>
              <li>WebSocket聊天室</li>
              <li>celery异步</li>

              <li>LangChain框架</li>
              <li><b style="color: red;">Agent自动化流程</b></li>
              <li><b  style="color: red;">rag避免模型幻觉问题，弥补知识缺失 </b> </li>
              <li><b  style="color: red;">prompt提示词的构建</b></li>
            </ul>
          </div>
        </div>
      </div>
      
      <div class="section">
        <h2 class="section-title">✨ 核心功能与实现细节</h2>
        <div class="feature-card detailed">
            <div class="feature-icon">🤖</div>
            <h3>rag向量存储</h3>
            <div class="tech-details">
              <p>rag向量化存储的步骤分为四步 数据获取，数据分割，文本向量化，向量化存储,向量化检索</p>
               其中最重要的是前两部数据的获取和数据的分割，如果仅仅只是读取文件的内容，将他使用递归切割法,那么这样的的数据是不满足企业级开发条件的
               <br>
               <br>
               他可能出现语义缺失问题，这时候我们就需要使用语义切割器，基于预先相似度再语意突变点进行切割，保留完整语义单元，提升检索准确性
               。要么再数据收集阶段对数据做一个预处理，将数据按照一定的规则进行整理如json格式，这样在后续的向量存储阶段，就可以直接使用切割获取到数据，避免重复的切割操作，提高效率。
               <br>
               <br>
               这是最常用的两种解决方案，当然我们也可以再数据收集阶段对数据做一些敏感词过滤，去除一些无用的数据，提高向量存储的准确性。
               <br>
               <br>
              rag也经常用于做模型的评估，通过rag的向量化数据库中的内容和模型生成的向量进行对比，可以评估模型的准确性，同时也可以通过rag的向量化数据库中的内容进行模型的训练，提高模型的准确性。

              <br>
              <br>
              我们也不仅仅只是从文档中读取也可以从pdf中读取，需要使用ocr图像识别技术，在后面我们也会使用python-docx等模块读取文件内容，而不是使用langchain自带的word_document 它太重了
             这也只是最基础的用法，后面你们还会学到多路召回（让模型返回多个结果,与rag向量化中的内容和模型向量对比看看那个更合适），es混合检索（es搜索引擎的倒排索引检测关键字，rag检测余弦相似度两者结合找到最佳的模型向量并返回他）
            


            </div>
          </div>
          <div class="feature-card detailed">
            <div class="feature-icon">🤖</div>
            <h3>prompt提示词的构建</h3>
            <div class="tech-details">
              <p>提示词是我们在学习大模型中最重要的一环，一个优秀的prompt几个要素包含几个要素：
                <br>1.上下文/角色（提供场景：说明使用背景和目的//设定角色：明确AI的角色定位），<b>必填</b>
                <br>2.明确的任务指令/问题，<b>必填</b>
                <br>3.示例示范(提供样例：展示输入-输出正确的情况,对参数，函数进行解释说明)  <b>必填</b>
                <br>4.输出格式要求(结构化指示：明确指定输出格式//可视化元素：要求使用列表、表格、代码块)
                <br>5.约束条件(长度限制：明确字数或段落要求//风格限制：指定正式/非正式等风格//排除内容：说明不应包含的内容)
                <br>6.逐步思考指示(分步引导：要求展示推理过程//中间验证：设置检查点) <b>必填</b>
                <br>7.评估标准(质量指标：明确什么是好的输出//评分维度：列出评估要点)  <b>必填</b></p>
                <br>
                <p>
                  agent自动化流程其实就是将我们编写的一个个方法/函数/类或什么别的东西 通过prompt的方式，让大模型串联起来我们通过明确业务逻辑业务关系调整他们的执行顺序，然后返回结果，这个prompt就是agent的核心，也是agent的灵魂，agent的prompt写的好，那么agent就能更好的完成任务，反之则反之
                  
                </p>

                <br>
                我们需要认识到一个好的提示词无论是对你写前端还是后端都是非常重要的，因为提示词决定了你的模型返回的结果，所以我们需要对提示词进行优化，让我们的模型返回的结果更加符合我们的需求，
                甚至可以说你要是会写提示词，你就能独立一个人完成我们的这个项目了，甚至是世界上任何大模型项目
            
            
              </div>
          </div>
          <div class="feature-card detailed">
            <div class="feature-icon">🤖</div>
            <h3>agent的介绍</h3>
            <div class="tech-details">
              <p>agent 的概念是Agent 是 LangChain 中能够自主决定采取何种行动以实现目标的组件。它可以与语言模型以及外部工具进行交互，根据当前的任务状态和环境信息，动态地选择合适的操作，如调用特定的 API、查询数据库或者对语言模型进行进一步的提问。其作用是增强语言模型应用的灵活性和适应性，使其能够处理更复杂、需要多种操作组合才能完成的任务</p>
              <br>
              它分为一个又一个的节点,它们在langchain框架中使用@tool 进行链接，在tools=[]这个列表中配置，在<br>agent_executor = AgentExecutor(<br>
    agent=agent,<br>
    tools=tools,<br>
    verbose=True ,  <br>
    handle_parsing_errors=True <b>#这个能自动解决一些错误务必开启</b> <br>
)，<br>
      中执行它的优势在于能结合第三方（数据库,api,函数，方法）将他们联合起来执行一个相对复杂的功能<br>
              <br>
              agent是langchain框架中最简单的一环但也是我们未来求职对的核心竞争力希望大家重视起来


            </div>
          </div>
        <div class="features">
          <div class="feature-card detailed">
            <div class="feature-icon">🔐</div>
            <h3>用户认证系统</h3>
            <div class="tech-details">
              <p>（使用了第三方钉钉登录,GitHub登录,重点解决了jwt的持久化问题从两个方面入手,a.主动退出将剩余的生命周期添加redis设置缓存时间黑名单机制,在中间件中检测是否存在于黑名单中 b.生成token额外生成一份retoken 通过中间件在发起请求之前将token替换未retoken延长生命周期 ）</p>
            </div>
          </div>
          
          <div class="feature-card detailed">
            <div class="feature-icon">⚡</div>
            <h3>高性能缓存</h3>
            <div class="tech-details">
              <p>（对首页内容使用redis的setnx 加锁进行缓存 即实现了：大量用户访问时限制一个用户从mysql中读取，并将其添加到redis中，其他用户从reids中读取）</p>
            </div>
          </div>
          
          <div class="feature-card detailed">
            <div class="feature-icon">💬</div>
            <h3>实时聊天</h3>
            <div class="tech-details">
              <p>使用websocket框架执行你们应该用不上，有兴趣可以来找我，我可以教你,就不过多介绍了打字好累</p>
            </div>
          </div>
          
          <div class="feature-card detailed">
            <div class="feature-icon">🌐 </div>
            <h3>百度云api</h3>
            <div class="tech-details">
              <p>百度智能云api文档就更简单了，他有ai演示的现成代码，只需要申请到key 正确输入就能使用，只不过他需要将参数携带到jwt请求体中间</p>
            </div>
          </div>
          
          <div class="feature-card detailed">
            <div class="feature-icon">🌐</div>
            <h3>云存储方案</h3>
            <div class="tech-details">
              <p>使用该技术不仅仅能节省本地存储空间，还能提高网站访问速度，而且在项目中使用的百度智能云他只能读取外网可访问的图片,或者是将本地图片以base64的编码形式处理,这里使用的是七牛云</p>
            </div>
          </div>
          
          <div class="feature-card detailed">
            <div class="feature-icon">💰</div>
            <h3>支付系统</h3>
            <div class="tech-details">
              <p>支付账户是：vcveib1281@sandbox.com <br>支付密码为：111111</p>
            </div>
          </div>
          
          <div class="feature-card detailed">
            <div class="feature-icon">🗣️</div>
            <h3>语音识别</h3>
            <div class="tech-details">
              <p>语音识别是将文字转为语音，但是它的返回类型需要自己处理，不方便携带另外的参数，建议使用base64编码处理</p>
            </div>
          </div>
          
          <div class="feature-card detailed">
            <div class="feature-icon">🗺️</div>
            <h3>地图定位</h3>
            <div class="tech-details">
              <p>使用的是api文档进行开发，这种大公司的api文档使用起来还是非常方便好用的，相当一部分的api文档都是使用requests库来使用的，在使用过程中只需要根据官方文档的指引获取到key 拿到token然后根据文档中提示的http方法,执行url并且携带参数就行了</p>
            </div>
          </div>
          
          <div class="feature-card detailed">
            <div class="feature-icon">✍</div>
            <h2>审核模块使用须知</h2>
            <div class="tech-details">
              <p>审核模块是我们项目中亮点，使用前你需要先执行celery -A mypro worker --pool=solo --loglevel=info <br>
                 因为审核的agent执行流程过长所以使用了celery （提交保险审核时，不要离开页面否则可能会出现问题，执行时间较长多等等无论成功或者失败都会有响应，看到响应为准，前端状态判断有问题，审核失败其实是通过了）

              
              </p>
            </div>
          </div>
          <div class="feature-card detailed">
            <div class="feature-icon">🗣️</div>
            <h3>celery异步</h3>
            <div class="tech-details">
              <p>celery异步，要写他我们首先需要了解异步的执行原理，简单来说就是他有一个生产者负责找事情加到任务队列中，有一个消费者负责做事，消费者需要实时监听任务队列来处理任务
                <br>
                celery比较难得是他的基础配置，配置完成之后，我们就像使用装饰器一样@shared_task
                ，在view视图层传递/获取参数然后，在setting配置好的异步文件中执行，执行完成之后，我们就可以在数据库中查询到结果，然后返回给前端
              </p>
            </div>
          </div>
          <div class="feature-card detailed">
            <div class="feature-icon">✍</div>
            <h3>审核模块介绍一</h3>
            <div class="tech-details">
              <p>
                 进行rag的向量化存储,获取my_file中的数据将其存储到rag中，对文件中的数据做了json化，因为数据格式不统一所以有些问题需要修改代码来存储，在rag封装中做了，数据类型的判断，并且将其使用不同的方法存储起来。并且做了敏感词的过滤。
                 在 语义分各种对txt文件类型的数据进行了语义分割，并且将向量检索和存储进行了分割，否则会出现my_file中的rag加载文件丢失rag数据库中的存储也跟着消失的问题
                

              </p>

            </div>
          </div>
          <div class="feature-card detailed">
            <div class="feature-icon">✍</div>
            <h3>审核模块介绍二</h3>
            <div class="tech-details">
              <p>审核模块核心节点一共使用了四个分别是 1.生成合同节点，2.合同审核节点，3.合同审核通过后修改mysql状态节点，4.前三条通过后将合同添加到rag向量存储中 ，*.模型评估审核若干（这部分不理想正在修改不确定最后改没改完，如果斌哥改好了，务必教教我）
              </p>
            </div>
          </div>
          <div class="feature-card detailed">
            <div class="feature-icon">⛅</div>
            <h3>天气查询</h3>
            <div class="tech-details">
              <p>天气查询调用百度api，百度提供了很全面的文档，配置起来很容易，不过要注意部分地区的查询存在错误，毕竟是免费接口，所以请自行判断</p>
            </div>
          </div>
          <div class="feature-card detailed">
            <div class="feature-icon">🎫</div>
            <h3>MongoDB查询</h3>
            <div class="tech-details">
              <p>使用mongodb数据库查询，这部分需要配置阿里云服务器，docker容器配置monggo，记得对内容编码，否则会出现乱码</p>
            </div>
          </div>
          <div class="feature-card detailed">
            <div class="feature-icon">⏰</div>
            <h3>Gitee登录</h3>
            <div class="tech-details">
              <p>在Gitee提供的的OAuth文档中有详细描述，流程比较容易理解，配置好gitee的appid和appsecret，然后使用gitee的api进行登录，登录成功之后，将用户信息存储到数据库中，然后返回给前端，前端根据返回的数据进行页面跳转</p>
            </div>
          </div>
          <div class="feature-card detailed">
            <div class="feature-icon">🎟️</div>
            <h3>首页展示</h3>
            <div class="tech-details">
              <p>考验对基础功能的掌握，Banner轮播图支持自动和手动滑动，提供快捷入口按钮和WelcomeItem.vue卡片快速跳转产品列表，用户中心等核心功能页面,用HomeView.vue作为首页面，使用Element Plus的el-row,el-col,el-card,el-carousel等组件进行响应式布局,</p>
            </div>
          </div>
          <div class="feature-card detailed">
            <div class="feature-icon">🌠</div>
            <h3>后台管理</h3>
            <div class="tech-details">
              <p>订单的增删改查，角色权限分配，不同角色访问不同模块例如：管理员开放管理中心能够对订单的删改、普通用户只开放用户中心，利用路由守护实现权限控制、身份校验、导航拦截与重定向</p>
            </div>
          </div>
          <div class="feature-card detailed">
            <div class="feature-icon">🎊</div>
            <h3>未完待续</h3>
            <div class="tech-details">
              <p></p>
            </div>
          </div>
        </div>
      </div>
      <h1>项目开发过程中的心得体会</h1>
      <div class="feature-card detailed">
            <div class="feature-icon">📠</div>
            <h3>前端页面开发</h3>
            <div class="tech-details">
              <p>
                是最简单的，也是最麻烦的，因为要考虑各种兼容性，后端的一个接口可能只用了半小时，但前端的页面可能要调一天。
                尤其是复杂的业务实现流程，和页面样式的匹配。<br><br>
                最要注意，小组开发时，尽量不要使用全局变量，使用局部变量，这样会更安全，不会出现变量污染。<br>
                另外，要考虑兼容性，比如IE浏览器，IE浏览器不支持async await，所以要使用promise。<br>
                页面一开始不要管匹配，先调出一个好看的页面，不然页面多了以后，改样式非常困难。
                </p>
            </div>
          </div>
          <div class="feature-card detailed">
            <div class="feature-icon">👁‍🗨</div>
            <h3>后端页面开发</h3>
            <div class="tech-details">
              <p>在项目的后端开发中遇到的问题，真的是非常非常多，其中大部分问题都是通过deepseek问题解决的，如果不是在ai大规模普及的现在,再给我们两倍的时间我们都开发不出来。
                    <br>
                    <br>
                    但是相比你们也有所体会ai也不是万能的，它只能解决我们提出的问题，不能无中生有，直接把我们自己都没有想象到的技术细节，页面样式，接口等开发完成
                    丢给我们所以我们在使用ai的时候一定要有自己思考的能力，所以有自己的思考就非常重要了，这里的的思考指的就是我们对业务的理解
                    ，对代码的熟悉起码要看明白这段代码在干什么
                    
                    <br><br>
                    不能完全依赖ai，我们之中已经出现代码是出来了，但是功能实现非常不理想，但是却无从下手修改因为代码都是ai生成的。

                 


              </p>
            </div>
          </div>

            <div class="feature-card detailed">
            <div class="feature-icon">🎁</div>
            <h3>寄语</h3>
            <div class="tech-details">
              <p>灵活思维，严密逻辑，扎实基础，是你走向更远的依仗</p>
              <p>愿你千帆竞过，如长虹，剑指苍穹</p>
            </div>
          </div>





    </div>
  </div>
</template>

<style scoped>
.about {
  min-height: 100vh;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  padding: 2rem;
  display: flex;
  justify-content: center;
  align-items: flex-start;
}

.thank-container {
  max-width: 1200px;
  width: 100%;
  background: white;
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
  padding: 2.5rem;
  margin: 2rem 0;
}

.thank-title {
  text-align: center;
  color: #3a7bd5;
  font-size: 2.5rem;
  margin-bottom: 2rem;
  position: relative;
}

.thank-title::after {
  content: "";
  display: block;
  width: 100px;
  height: 4px;
  background: linear-gradient(to right, #3a7bd5, #00d2ff);
  margin: 0.5rem auto;
  border-radius: 2px;
}

.section {
  margin-bottom: 3rem;
}

.section-title {
  color: #4a6fa5;
  font-size: 1.8rem;
  margin-bottom: 1.5rem;
  padding-bottom: 0.5rem;
  border-bottom: 2px solid #eaeff5;
}

.team-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1.5rem;
  margin-bottom: 1.5rem;
}

.team-member {
  background: #f8f9fa;
  padding: 1.2rem;
  border-radius: 8px;
  text-align: center;
  transition: transform 0.3s, box-shadow 0.3s;
}

.team-member:hover {
  transform: translateY(-5px);
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}

.role {
  font-weight: 600;
  color: #6c757d;
  margin-bottom: 0.5rem;
}

.name {
  font-size: 1.2rem;
  color: #343a40;
  font-weight: 700;
}

.project-duration {
  text-align: center;
  font-size: 1.1rem;
  color: #6c757d;
  font-style: italic;
}

.tech-stack {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
}

.tech-category {
  background: #f8f9fa;
  padding: 1.5rem;
  border-radius: 8px;
}

.tech-category h3 {
  color: #4a6fa5;
  margin-bottom: 1rem;
  font-size: 1.3rem;
}

.tech-category ul {
  list-style-type: none;
  padding-left: 0;
}

.tech-category li {
  padding: 0.5rem 0;
  color: #495057;
  position: relative;
  padding-left: 1.5rem;
}

.tech-category li::before {
  content: "•";
  color: #3a7bd5;
  font-size: 1.2rem;
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
}

.features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
}

.feature-card {
  background: white;
  border: 1px solid #eaeff5;
  border-radius: 8px;
  padding: 1.5rem;
  transition: transform 0.3s, box-shadow 0.3s;
}

.feature-card.detailed {
  display: flex;
  flex-direction: column;
}

.feature-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}

.feature-icon {
  font-size: 2rem;
  margin-bottom: 1rem;
}

.feature-card h3 {
  color: #4a6fa5;
  margin-bottom: 0.8rem;
}

.tech-details {
  background: #f8f9fa;
  padding: 1rem;
  border-radius: 6px;
  margin-top: 0.5rem;
  flex-grow: 1;
}

.tech-details p {
  color: #495057;
  line-height: 1.6;
  font-size: 0.95rem;
  margin: 0;
}

@media (max-width: 768px) {
  .thank-container {
    padding: 1.5rem;
  }
  
  .team-grid, .tech-stack, .features {
    grid-template-columns: 1fr;
  }
}
</style>